<?php

namespace App\Logics;


use App\Jobs\CourseCycleJob;
use App\Models\Course;
use App\Models\CourseCycle;
use App\Models\CourseSign;
use App\Models\CourseStudent;
use App\Models\CourseTimes;
use App\Models\Student;
use App\Models\User;
use App\Models\UserAuth;
use App\Service\Base\Logic;
use Illuminate\Support\Facades\DB;

class CourseLogic extends Logic
{


    // 添加课程
    //  添加学员
    //  添加课时


    // 课程列表
    //   我添加的课程
    //   提醒我的课程


    // 列表查询
    //  周期、学员数，学员接入数
    //  剩余课时、
    public function onLists()
    {
        $option = $this->option();
        $page   = $option->getData('page', 1, 'intval');
        $rows   = $option->getData('rows', 15, 'intval');
        $isPage = $option->getData('is_count', 0, 'intval');  // 是否需要翻页
        $start  = ($page - 1) * $rows;

        $lRes  = $this->listWhere();
        $where = $lRes[0];
        // 模型
        $model  = new Course();
        $KCache = $model->cacheKey('lists', $where);
        $result = $model->cacheClass()->getCache($KCache);
        // 检查是否已经绑定
        if(!empty($result)){
            if($isPage){
                if(!empty($result['list'])){
                    $model->checkBangList($result['list'], $KCache);
                }
            } else{
                $model->checkBangList($result, $KCache);
            }
        }

        // ->bangField($bang)
        if(empty($result)){
            if($isPage){
                $result = $model->listPage($where, $page, $rows, "id DESC");
            } else{
                $result = $model->getList($where, $rows, "id DESC", $start);
                $result = is_object($result) ? $result->toArray() : $result;
            }
            /*if($where != false){
                $model->addCacheList($lists, $KCache, $lists, 'list');
            }*/
        }

        // 查询我的剩余课程
        if(!empty($result['list'])){
            $courseStuDb   = new CourseStudent();
            $courseCycleDb = new CourseCycle();
            $courseTimeDb  = new CourseTimes();
            $userAuthDb    = new UserAuth();
            $studentDb     = new Student();
            foreach($result['list'] as &$item){
                $_auth  = $userAuthDb->isCache(true)->oneFind(['uid' => $item['uid']]);
                $_times = $courseTimeDb->isCache(true)->getList(['course_id' => $item['id']], 0, 'number ASC');
                $_cycle = $courseCycleDb->isCache(true)->getList(['course_id' => $item['id']], 0);
                $_cStus = $courseStuDb->isCache(true)->getList(['course_id' => $item['id']], 0);
                $_stus  = $studentDb->isCache(true)->getListInIds(array_column($_cStus, 'student_id'));    // 学员信息

                // 剩余课程数 课程时间 >当前时间 的数量
                $sign_times = 0;  // 已经上课的数量
                foreach($_times as $_time){
                    if($_time['start_time'] < LARAVEL_TIME){
                        $sign_times++;
                    }
                }
                // 学员数 与 学员接入数
                $_number = $_access = 0;
                foreach($_stus as $_stu){
                    if($_stu['status'] == 1){
                        $_number++;
                    }
                    if($_stu['status'] > 0){
                        $_access++;
                    }
                }

                // 组合周期
                foreach($_cycle as &$_cy){
                    $_cy['start_time_format'] = date('H:i', $_cy['start_time'] - 8 * 3600);
                    $_cy['end_time']          = 0;
                }

                // 整合
                $item['student_number'] = $_number; // 接入数
                $item['student_access'] = $_access; // 学员数
                $item['sign_times']     = $sign_times; // 上课数
                $item['left_times']     = $item['times'] - $sign_times;  // 剩余数量
                $item['user_auth']      = $_auth;
                $item['all_times']      = $_times;
                $item['all_cycle']      = $_cycle;
            }
        }


        return $result;
    }

    // 统计：主要用户pc端
    public function onCount()
    {
        $lRes  = $this->listWhere();
        $where = $lRes[0];

        // 执行
        $rows   = $this->option()->getData('rows', 15, 'intval');
        $model  = new Course();
        $nums   = $model->where($where)->count();
        $pages  = ceil($nums / $rows);
        $result = ['total' => $nums, 'pages' => $pages,];

        return $result;
    }


    // 学生的提醒课程
    public function studentCourse($myUid = 0)
    {
        $option = $this->option();
        $page   = $option->getData('page', 1, 'intval');
        $rows   = $option->getData('rows', 15, 'intval');
        $c_id   = $option->getData('course_id', 0, 'intval');
        $start  = ($page - 1) * $rows;

        // 模型 和 查询
        $where = [];
        $cMap  = [];
        $bang  = [];
        if($c_id){
            $bang[]  = 'course_id';
            $where[] = ['course.id', '=', $c_id];
            $cMap[]  = ['course.id', '=', $c_id];
        }
        if($myUid){
            // 查找自己的学员ID
            $stuList = (new Student())->where('person_uid', $myUid)->get()->toArray();
            if(empty($stuList)){
                return $result = ['total' => 0, 'page' => $page, 'rows' => $rows, 'list' => [],];
            }

            $stuIds  = array_column($stuList, 'id');
            $stuList = array_column($stuList, null, 'id');
            $bang[]  = 'student_id';
            $cMap[]  = ['student.student_id', 'in', $stuIds];
        }


        // 模型
        $model  = new Course();
        $KCache = $model->cacheKey('lists', $cMap);
        $result = $model->cacheClass()->getCache($KCache);
        // 检查是否已经绑定
        // 检查是否已经绑定
        if(($result) && (!empty($result['list']))){
            $model->checkBangList($result['list'], $KCache);
        }
        if(empty($result)){
            $query = $model->from('course as model')->where($where)->select(['model.*', 'student.student_id'])->join('course_student as student', 'student.course_id', '=', 'model.id');
            if(!empty($stuIds)){
                $query = $query->whereIn('student.student_id', $stuIds);
            }

            // 执行
            $count  = $query->count();
            $lists  = $query->forPage($page, $rows)->orderBy('model.id', 'DESC')->get()->toArray();
            $result = ['total' => $count, 'page' => $page, 'rows' => $rows, 'list' => $lists,];
            if($where != false){
                $model->bangField($bang)->addCacheList($lists, $KCache, $result, 'list');
            }
        }

        // 查询我的剩余课程
        if(!empty($result['list']) && $myUid){
            $courseStuDb   = new CourseStudent();
            $courseTimeDb  = new CourseTimes();
            $userAuthDb    = new UserAuth();
            $courseCycleDb = new CourseCycle();
            foreach($result['list'] as &$item){
                $_auth  = $userAuthDb->isCache(true)->oneFind(['uid' => $item['uid']]);
                $_info  = $courseStuDb->isCache(true)->oneFind(['student_id' => $myUid, 'course_id' => $item['id']]);
                $_times = $courseTimeDb->isCache(true)->getList(['course_id' => $item['id']], 0, 'number ASC');
                $_cycle = $courseCycleDb->isCache(true)->getList(['course_id' => $item['id']], 0);

                // 组合周期
                foreach($_cycle as &$_cy){
                    $_cy['start_time_format'] = date('H:i', $_cy['start_time'] - 8 * 3600);
                    $_cy['end_time']          = 0;
                }

                // 整合
                $item['student']    = $stuList[$item['student_id']] ?? [];
                $item['user_auth']  = $_auth;
                $item['all_times']  = $_times;
                $item['all_cycle']  = $_cycle;
                $item['sign_times'] = $_info['sign_times'] ?? 0;
                $item['left_times'] = $item['times'] - $item['sign_times'];
            }
        }


        return $result;
    }

    // 课程详情
    //  学员课程：返回课程信息，课程时间，自己签到
    //  学校课程：返回课程信息，课程时间，课程签到，课程学员

    //   发布者的详情
    //   上课时间
    public function onShow($myUid)
    {
        $option    = $this->option();
        $c_id      = $option->getData('id', 0, 'intval');
        $courseDb  = new Course();
        $timesDb   = new CourseTimes();
        $studentDb = new CourseStudent();
        $signDb    = new CourseSign();
        // 课程信息
        //$info = $courseDb->isCache(true)->oneFind(['id' => $c_id]);
        $info = $courseDb->where(['id' => $c_id])->first();
        if(empty($info)){
            return $this->_returnFail($courseDb->getError());
        }

        // 课程的课时
        $info   = is_object($info) ? $info->toArray() : $info;
        $_times = $timesDb->isCache(true)->getList(['course_id' => $c_id], 0, 'number ASC');

        // 课程学员
        $students = $studentDb->bangField(['course_id'])->getList(['course_id' => $c_id]);
        $students = $students ?: [];

        /*if($students===false){
            return $this->_returnFail($studentDb->getError());
        }*/

        // 课程签到
        //  TODO 签到的学员，每一个课程，多个课时签到
        $signs = $signDb->bangField(['course_id'])->getList(['course_id' => $c_id,]); //  'time_id' => $inTimeId
        $signs = $signs ?: [];
        /*if($signs===false){
            return $this->_returnFail($signDb->getError());
        }*/

        // 整理数据
        $sids  = array_merge(array_column($students, 'student_id'), array_column($signs, 'student_id'));
        $sids  = array_column($students, 'student_id');
        $users = (new Student())->isCache(true)->getListInIds($sids);
        foreach($students as &$_item){
            $_item['student'] = $users[$_item['student_id']] ?? [];
        }

        //$this->log($students, '课程学员信息');
        //$this->log($sids, '课程学员ID');
        // 签到情况
        $allSign = [];
        foreach($signs as $_it){
            //$_item['student'] = $users[$_item['student_id']] ?? [];
            $allSign[$_it['time_id']][$_it['student_id']] = $_it;
        }
        // 上课次数
        // 剩余课程数 课程时间 >当前时间 的数量
        $left_times = 0;  // 已经上课的数量
        $inTimeId   = 0;  // 下次上课时间 前后60分钟内都算 3600
        $s_time     = LARAVEL_TIME - 3600;
        $e_time     = LARAVEL_TIME + 3600;
        foreach($_times as &$_time){
            $_tid = $_time['id'];
            if($_time['start_time'] > LARAVEL_TIME){
                $left_times++;
            }
            // 是否上课
            $_time['in_time'] = 0;
            if(($_time['start_time'] > $s_time) && ($_time['start_time'] < $e_time)){
                $_time['in_time'] = 1;
                $inTimeId         = $_time['id'];
            }

            // 学员 与 签到
            $_sign = 0;  // 签到状态
            foreach($students as $_student){
                // 签到情况
                if(isset($allSign[$_tid][$_student['id']])){
                    $_sign = $allSign[$_tid][$_student['id']]['status'];
                }
                // 整理
                $_student['sign_status'] = $_sign;
                $_time['students'][]     = $_student;
            }
        }

        // 整理
        $info['left_times'] = $left_times; // 剩余数量
        $info['sign_times'] = $info['times'] - $left_times;  // 上课数
        $info['all_times']  = $_times;
        $info['signs']      = $signs;
        $info['students']   = $students;

        return $info;
    }


    //   提醒我的课程详情
    public function onStudentShow($myUid)
    {
        $option     = $this->option();
        $c_id       = $option->getData('id', 0, 'intval');
        $courseDb   = new Course();
        $timesDb    = new CourseTimes();
        $studentDb  = new Student();
        $cStudentDb = new CourseStudent();
        $signDb     = new CourseSign();
        $userAuthDb = new UserAuth();
        // 课程信息
        $info = $courseDb->isCache(true)->oneFind(['id' => $c_id]);
        if(empty($info)){
            return $this->_returnFail($courseDb->getError());
        }
        // 学校
        $_auth = $userAuthDb->isCache(true)->oneFind(['uid' => $info['uid']]);
        // 课程时间
        $_times = $timesDb->bangField(['course_id'])->getList(['course_id' => $c_id], 0, 'number ASC');
        if($_times === false){
            return $this->_returnFail($timesDb->getError());
        }

        // 学员信息

        $_student = $studentDb->isCache(true)->oneFind(['person_uid' => $myUid, 'auth_id' => $_auth['id']]);
        if($_student === false){
            return $this->_returnFail($studentDb->getError());
        }
        if(empty($_student)){
            return $this->_returnFail('你不是这个学校的学员！');
        }

        // 课程签到 course_uid:可能为0
        // $signs = $signDb->bangField(['course_id', 'course_uid'])->getList(['course_id' => $c_id, 'course_uid' => $myUid]);
        $signs = $signDb->bangField(['course_id', 'course_uid'])->getList(['course_id' => $c_id, 'student_id' => $_student['id']]);
        if($signs === false){
            return $this->_returnFail($signDb->getError());
        }

        // 课程学员信息
        $_cstudent = $cStudentDb->isCache(true)->oneFind(['student_id' => $_student['id'], 'course_id' => $c_id]);
        if($_cstudent === false){
            return $this->_returnFail($cStudentDb->getError());
        }
        if(empty($_cstudent)){
            return $this->_returnFail('你没有选择这个课程！');
        }

        // 上课次数
        // 剩余课程数 课程时间 >当前时间 的数量
        $_signs     = array_column($signs, null, 'time_id');
        $left_times = 0;  // 已经上课的数量
        $inTimeId   = 0;  // 下次上课时间 前后60分钟内都算 3600
        $s_time     = LARAVEL_TIME - 3600;
        $e_time     = LARAVEL_TIME + 3600;
        foreach($_times as &$_time){
            $_tid  = $_time['id'];
            $_sign = 0;
            // 签到
            if(isset($_signs[$_tid])){
                $_sign = $_signs[$_tid]['status'];
            }
            // 上课次数
            if($_time['start_time'] > LARAVEL_TIME){
                $left_times++;
            }
            // 是否上课
            $_time['in_time']     = 0;
            $_time['sign_status'] = $_sign;  // 签到状态 0-未签到 1-签到 2-请假
            if(($_time['start_time'] > $s_time) && ($_time['start_time'] < $e_time)){
                $_time['in_time'] = 1;
                $inTimeId         = $_time['id'];
            }
        }

        // 整理
        $info['all_times']  = $_times;
        $info['user_auth']  = $_auth;
        $info['signs']      = $signs;
        $info['student']    = $_student;
        $info['sign_times'] = $_cstudent['sign_times'];
        $info['left_times'] = $info['times'] - $_cstudent['sign_times'];

        return $info;
    }

    // 直接删除课程：pc使用
    public function onDelete($myUid)
    {
        $opt = $this->option();
        $_id = $opt->getData('id', 0, 'intval');
        if(empty($_id)){
            return $this->_returnFail('请指定删除记录');
        }

        $where  = ['id' => $_id, 'uid' => $myUid];
        $model  = new Course();
        $result = $model->isCache(true)->oneDelete($where);
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        return $result;
    }


    // 直接删除课程：pc使用
    public function batchDelete($myUid)
    {
        $opt  = $this->option();
        $_ids = $opt->getData('ids', [], 'is_array');
        if(empty($_ids)){
            return $this->_returnFail('请指定删除记录');
        }

        $where = ['uid' => $myUid];
        $model = new Course();
        $list  = $model->whereIn('id', $_ids)->where($where)->get();  //->recycle()
        if($list->isEmpty()){
            return $this->_returnFail('你要删除的数据不存在！！');
        }

        // 缓存操作
        $model->deleteCacheList($list);
        $res = $model->whereIn('id', $_ids)->where($where)->delete();  //->recycle()

        return $res;
    }


    // 课程签到
    // 课程请假
    public function onSign()
    {
        $option  = $this->option();
        $status  = $option->getData('status', 1, 'intval');  // 状态 0-未到 1-正常 2-请假
        $c_id    = $option->getData('course_id', 0, 'intval');
        $s_id    = $option->getData('student_id', 0, 'intval');
        $time_id = $option->getData('time_id', 0, 'intval');
        $_uid    = $option->getData('uid', 0, 'intval');  // 如果是学员，看自己的课程信息
        if(empty($c_id)){
            return $this->_returnFail('请指定签到课程！');
        }
        if(empty($time_id)){
            return $this->_returnFail('请指定签到课时！');
        }

        $courseDb  = new Course();
        $studentDb = new Student();
        $cStuDb    = new CourseStudent();
        // 查询课程信息
        $info = $courseDb->isCache(true)->oneFind(['id' => $c_id]);
        if(empty($info)){
            return $this->_returnFail($courseDb->getError());
        }

        // 查询学员信息 获取这个学员的学员ID
        //    一个学员可能被多个机构添加
        if(empty($s_id)){
            if(empty($_uid)){
                return $this->_returnFail('请指定请假用户！');
            }

            $stuWhere = ['uid' => $info['uid'], 'person_uid' => $_uid, 'status' => 1];
            $stuInfo  = $studentDb->isCache(true)->oneFind($stuWhere);
            if(empty($stuInfo)){
                return $this->_returnFail('学员不存在！');
            }

            $s_id = $stuInfo['id'];
        }

        // 查看课程学员信息
        $cWhere = [['student_id', '=', $s_id], ['course_id', '=', $c_id]];
        $sinfo  = $cStuDb->isCache(true)->lockForUpdate()->where($cWhere)->first();
        //$sinfo  = $cStuDb->isCache(true)->oneFind($cWhere);
        if(empty($sinfo)){
            return $this->_returnFail('该学员不存在与这个课程中！');
        }

        // 判断是否已经请假或者签到
        $model    = new CourseSign();
        $singInfo = $model->isCache(true)->oneFind(['time_id' => $time_id, 'student_id' => $sinfo['id'],]);
        if($singInfo){
            return $this->_returnFail('你已经请假或者签到了！');
        }

        // 组合
        $data = [
            'uid'        => $info['uid'],
            'course_id'  => $c_id,
            'time_id'    => $time_id,
            'student_id' => $s_id,
            'course_uid' => $sinfo['course_uid'],
            'status'     => $status,  // 状态 0-未到 1-正常 2-请假
            'up_time'    => '0',
            'is_up'      => '0',
        ];

        $data = $this->filterNull($data);
        if(empty($data)){
            return $this->_returnFail('请添加需要保存的数据！');
        }

        // 组合数据
        $data = $model->checkData($data);
        if($data === false){
            return $this->_returnFail('请添加需要保存的数据！');
        }

        // 验证
        $result = $model->checkRules($data, 'add');
        if($result === false){
            return $this->_returnFail($model->getError());
        }


        // 执行
        DB::beginTransaction();
        try{
            // 保存
            $model->fill($data);
            $result = $model->save();

            // 改变我的上课课时
            $cStuDb->where($cWhere)->update(['sign_times' => DB::raw('sign_times+1')]);

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->_returnFail($e->getMessage());
        }


        // 缓存操作
        $model->deleteCacheShow($data);
        $cStuDb->deleteCacheShow($sinfo);

        /*$result = $model->oneAdd($data);
        if($result === false){
            return $this->_returnFail($model->getError());
        }*/

        return $model->id;
    }

    // 批量签到  student_ids
    public function bathSign()
    {
        $option  = $this->option();
        $c_id    = $option->getData('course_id', 0, 'intval');
        $s_ids   = $option->getData('student_ids', [], 'is_array');
        $time_id = $option->getData('time_id', 0, 'intval');
        if(empty($c_id)){
            return $this->_returnFail('请指定签到课程！');
        }
        if(empty($time_id)){
            return $this->_returnFail('请指定签到课时！');
        }
        if(empty($s_ids)){
            return $this->_returnFail('请指定签到学员！');
        }

        $courseDb  = new Course();
        $studentDb = new Student();
        // 查询课程信息
        $info = $courseDb->isCache(true)->oneFind(['id' => $c_id]);
        if(empty($info)){
            return $this->_returnFail($courseDb->getError());
        }

        // 查询学员信息
        $students = [];
        foreach($s_ids as $s_id){
            if(empty($s_id)){
                return $this->_returnFail('请指定签到学员！');
            }

            // 查询学员信息
            $where = [['uid', '=', $info['uid']], ['id', '=', $s_id]];
            $sinfo = $studentDb->isCache(true)->oneFind($where);
            if(empty($sinfo)){
                return $this->_returnFail('该学员不存在！');
            }

            // 组合
            $students[] = $sinfo;
        }

        // 判断是否已经请假或者签到
        $model    = new CourseSign();
        $stuIds   = array_column($students, 'id');
        $singInfo = $model->where('time_id', $time_id)->whereIn('student_id', $stuIds)->first();
        if($singInfo){
            return $this->_returnFail('你选择的学员已经请假或者签到了！');
        }

        // 组合
        foreach($students as $_student){
            // 签到数据
            $data[] = [
                'uid'        => $info['uid'],
                'course_id'  => $c_id,
                'time_id'    => $time_id,
                'student_id' => $_student['id'],
                'course_uid' => $_student['person_uid'],
                'status'     => 1,  // 状态 0-未到 1-正常 2-请假
                'up_time'    => '0',
                'is_up'      => '0',
                'ctime'      => LARAVEL_TIME,
                'mtime'      => LARAVEL_TIME,
            ];
        }

        // 查询课程学员是否在这个课程中
        $cStuDb = new CourseStudent();
        $slist  = $cStuDb->isCache(true)->lockForUpdate()->where('course_id', $c_id)->whereIn('student_id', $s_ids)->get()->toArray();
        if(count($slist) != count($s_ids)){
            return $this->_returnFail('有学员不存在与这个课程中！');
        }

        // 执行
        DB::beginTransaction();
        try{
            // 保存
            $result = $model->insert($data);

            // 改变我的上课课时
            $cStuDb->where('course_id', $c_id)->whereIn('student_id', $s_ids)->update(['sign_times' => DB::raw('sign_times+1')]);

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->_returnFail($e->getMessage());
        }

        // 缓存操作
        $model->deleteCacheList($data);

        return $result;
    }

    // 签到记录
    public function signLists()
    {
        $option = $this->option();
        $c_id   = $option->getData('course_id', 0, 'intval');
        $_uid   = $option->getData('uid', 0, 'intval');  // 如果是学员，看自己的课程信息
        $signDb = new CourseSign();

        // 如果是添加课程的用户 则可以看到所有的签到
        //  如果是学员，只能看到自己的签到
        $courseDb  = new Course();
        $studentDb = new Student();
        $cStuDb    = new CourseStudent();
        // 查询课程信息
        $info = $courseDb->isCache(true)->oneFind(['id' => $c_id]);
        if(empty($info)){
            return $this->_returnFail($courseDb->getError());
        }

        // 课程签到
        if($_uid != $info['uid']){
            // 学员看自己的签到信息
            // 获取学员的ID
            $sinfo = $studentDb->isCache(true)->oneFind(['uid' => $info['uid'], 'person_uid' => $_uid]);
            if(empty($sinfo)){
                return $this->_returnFail($courseDb->getError());
            }

            $signs = $signDb->bangField(['course_id', 'student_id'])->getList(['course_id' => $c_id, 'student_id' => $sinfo['id']], 0);
            if($signs === false){
                return $this->_returnFail($signDb->getError());
            }
        } else{
            //  TODO 签到的学员，每一个课程，多个课时签到
            $signs = $signDb->bangField(['course_id'])->getList(['course_id' => $c_id], 0);
            if($signs === false){
                return $this->_returnFail($signDb->getError());
            }
            // 整理数据
            $sids  = array_column($signs, 'student_id');
            $users = (new Student())->isCache(true)->getListInIds($sids);
            foreach($signs as &$_item){
                $_item['student'] = $users[$_item['student_id']] ?? [];
            }
        }

        return $signs;
    }


    // 改变（直接修改，软删除，改变状态，排序）
    public function onEdit($myUid)
    {
        // 获取认证编号
        $user = $this->checkAuthUser($myUid);
        if($user === false){
            return false;
        }

        $opt = $this->option();
        $_id = $opt->getData('id', null, 'intval');
        if(empty($_id)){
            return $this->_returnFail('请指定修改的ID编号！');
        }


        $auth_id = $user['auth_id'];
        $data    = [
            //'id'          => $opt->getData("id", null, "trim"),
            'uid'         => $myUid,
            'auth_id'     => $auth_id,
            'name'        => $opt->getData("name", null, "trim"),
            'times'       => $opt->getData("times", null, "intval"),
            'start_time'  => $opt->getData("start_time", null, "strtotime"),
            'end_time'    => $opt->getData("end_time", null, "strtotime"),
            'city'        => $opt->getData("city", null, "trim"),
            'address'     => $opt->getData("address", null, "trim"),
            'description' => $opt->getData("description", null, "trim"),
            'status'      => $opt->getData("status", 1, "trim"),
            //'student'     => $opt->getData("student", [], "is_array"),
            'cycle'       => $opt->getData("cycle", [], "is_array"),
            //'ctime'       => $opt->getData("ctime", null, "trim"),
            //'mtime'       => $opt->getData("mtime", null, "trim"),
        ];
        if($data['end_time'] <= $data['start_time']){
            return $this->_returnFail('结束时间不能小于开始时间！');
        }

        // 测试时间应该到当天晚上
        $data['end_time'] = $data['end_time'] + 86400 - 1;

        $data = $this->filterNull($data);
        if(empty($data)){
            return $this->_returnFail('请添加需要保存的数据！');
        }

        // 组合数据
        $where = ['id' => $_id, 'uid' => $myUid];
        $model = new Course();
        $data  = $model->checkData($data, $where);
        if($data === false){
            return $this->_returnFail('请添加需要保存的数据！');
        }

        // 验证
        $result = $model->checkRules($data, 'edit');
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        // 检查周期
        $result = $this->checkCycle($data['cycle']);
        if($result === false){
            return $this->_returnFail($this->getError());
        }

        // 保存
        //  保存的时候：保存时间
        $result = $model->oneEdit($where, $data);
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        return $result;
    }

    // 树状
    public function onAdd($myUid)
    {
        // 获取认证编号
        $user = $this->checkAuthUser($myUid);
        if($user === false){
            return false;
        }

        $opt     = $this->option();
        $auth_id = $user['auth_id'];
        $data    = [
            //'id'          => $opt->getData("id", null, "intval"),
            'uid'         => $myUid,
            'auth_id'     => $auth_id,
            'name'        => $opt->getData("name", null, "trim"),
            'times'       => $opt->getData("times", null, "intval"),
            'start_time'  => $opt->getData("start_time", null, "strtotime"),
            'end_time'    => $opt->getData("end_time", null, "strtotime"),
            'city'        => $opt->getData("city", null, "trim"),
            'address'     => $opt->getData("address", null, "trim"),
            'description' => $opt->getData("description", null, "trim"),
            'status'      => $opt->getData("status", 1, "trim"),
            'student'     => $opt->getData("student", [], "is_array"),
            'cycle'       => $opt->getData("cycle", [], "is_array"),
            //'ctime'       => $opt->getData("ctime", null, "trim"),
            //'mtime'       => $opt->getData("mtime", null, "trim"),
        ];

        if($data['end_time'] <= $data['start_time']){
            return $this->_returnFail('结束时间不能小于开始时间！');
        }

        // 测试时间应该到当天晚上
        $data['end_time'] = $data['end_time'] + 86400 - 1;
        $data             = $this->filterNull($data);
        if(empty($data)){
            return $this->_returnFail('请添加需要保存的数据！');
        }

        // 组合数据
        $model = new Course();
        $data  = $model->checkData($data);
        if($data === false){
            return $this->_returnFail('请添加需要保存的数据！');
        }

        // 验证
        $result = $model->checkRules($data, 'add');
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        // 检查周期
        $result = $this->checkCycle($data['cycle']);
        if($result === false){
            return $this->_returnFail($this->getError());
        }

        // 保存
        $result = $model->oneAdd($data);
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        return $result;
    }

    // 检查 操作用户必须是认证用户
    public function checkAuthUser($myUid)
    {
        $user = (new User())->isCache(true)->oneFind(['id' => $myUid]);
        if(empty($user)){
            return $this->_returnFail('你选择的用户不存在！');
        }
        if(empty($user['is_auth'])){
            return $this->_returnFail('你不是认证用户！');
        }
        if($user['verify'] != 1){
            return $this->_returnFail('你选择的用户认证未通过！');
        }

        return $user;
    }

    // 检查周期保存的数据是否正确
    protected function checkCycle($cycle = [])
    {
        if(empty($cycle)){
            return true;
        }

        // 周期的参数解析
        foreach($cycle as $item){
            if(empty($item['cycle']) || empty($item['number']) || empty($item['hour']) || empty($item['minute'])){
                return $this->_returnFail('周期数据不完善！！');
            }

            // 周期的参数
            $_type   = $item['cycle'];
            $_number = $item['number'];
            $_hour   = $item['hour'];
            $_minute = $item['minute'];

            // 数据判断
            if(($_hour > 23) || ($_hour < 0)){
                return $this->_returnFail('周期中小时必须在0~23之间！！');
            }
            if(($_minute > 60) || ($_minute < 0)){
                return $this->_returnFail('周期中分数必须在0~59之间！！');
            }
            if($_type == 'week'){
                if(($_number > 7) || ($_number < 0)){
                    return $this->_returnFail('周期中选择每周number必须在1~7之间！！');
                }
            } elseif($_type == 'month'){
                if(($_number > 31) || ($_number < 0)){
                    return $this->_returnFail('周期中选择每月number必须在1~31之间！！');
                }
            }
        }

        return true;
    }

    // 队列消息：添加积分
    protected function addCourseJob($cid = 0)
    {
        // 发送任务
        //TaskJob::dispatchIf(true, $data)->onQueue('member_task');
        $data = ['course_id' => $cid];
        $res  = CourseCycleJob::dispatch($data)->onQueue('course_task');

        return $res;
    }

    // 搜索条件
    protected function listWhere()
    {
        $option = $this->option();
        // 模型 和 查询
        $where   = [];
        $bang    = [];
        $c_id    = $option->getData('course_id', 0, 'intval');
        $uid     = $option->getData('uid', 0, 'intval');
        $myUid   = $option->getData('myUid', 0, 'intval');
        $name    = $option->getData('name', null, 'trim');
        $keyword = $option->getData('keyword', null, 'trim');
        if($c_id){
            $bang[]  = 'id';
            $where[] = ['id', '=', $c_id];
        }
        if($uid){
            $bang[]  = 'uid';
            $where[] = ['uid', '=', $uid];
        }
        if($myUid){
            $bang[]  = 'uid';
            $where[] = ['uid', '=', $myUid];
        }
        if($name){
            $bang    = false;
            $where[] = ['name', 'like', "%".$name."%"];
        }

        return [$where, $bang];
    }
}


